// ActionScript file
package
{
	import mx.utils.ObjectUtil;
	import mx.collections.ArrayCollection;
	import mx.utils.ObjectProxy;
	import flash.utils.Dictionary;
	
	class TreeUtil
	{
		static var dict:Dictionary;
		static var numObj:Number = 0;
		
		static function toTree(obj)
		{
			var inspect = new Array();
			dict = new Dictionary();
			numObj = 0;
			
			inspectify(obj, inspect);
			
			if(inspect[0].children == null)
			{
				return inspect;
			}
			else
			{
				return inspect[0].children;
			}
		}
		
		static function inspectify(obj, node, baseLabel = "")
		{
			if(obj == null)
			{
				node.push({label:baseLabel + '(null)'});
				return;
			}
			else if(obj is Number || obj is Boolean)
			{
				node.push({label:baseLabel + obj.toString()});
			}
			else if(obj is String)
			{
				node.push({label:baseLabel + '"' + obj + '"'});
			}
			else if(obj is Date || obj is XML)
			{
				node.push({label:baseLabel + obj.toString()});
			}
			else if(obj is Array)
			{
				if(dict[obj] != null)
				{
					node.push({label:baseLabel + "(array) #" + dict[obj]});
					return;
				}
				dict[obj] = numObj++;
				var children = new Array();
				for(var i in obj)
				{
					inspectify(obj[i], children, i + ': ');
				}
				node.push({label:baseLabel + '(array) #' + dict[obj], children:children});
			}
			else if(obj is ArrayCollection)
			{
				if(dict[obj] != null)
				{
					node.push({label:baseLabel + "(object mx.collections.ArrayCollection) #" + dict[obj]});
					return;
				}
				dict[obj] = numObj++;
				var children = new Array();
				for(var i in obj)
				{
					inspectify(obj[i], children, i + ': ');
				}
				node.push({label:baseLabel + '(object mx.collections.ArrayCollection) #' + dict[obj], children:children});
			}
			else if(obj is ObjectProxy)
			{
				if(dict[obj.source] != null)
				{
					node.push({label:baseLabel + "(object mx.utils.ObjectProxy) #" + dict[obj]});
					return;
				}
				dict[obj.source] = numObj++;
				var innerObj = new Array();
				inspectify(obj.source, innerObj);
				node.push({label:baseLabel + '(object mx.utils.ObjectProxy) #' + dict[obj.source], childremn:innerObj});
			}
			else if(obj is Object)
			{
				if(dict[obj] != null)
				{
					node.push({label:baseLabel + "(object) #" + dict[obj]});
					return;
				}
				dict[obj] = numObj++;
                var classInfo:Object = ObjectUtil.getClassInfo(obj, null,
					{ includeReadOnly: true});
				var children = new Array();
				var props = classInfo.properties
				for(var i = 0; i < props.length; i++)
				{
					inspectify(obj[props[i]], children, props[i] + ': ');
				}
				node.push({label:baseLabel + '(object ' + classInfo.name + ') #' + dict[obj], children:children});
			}
		}
	}
}